﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;

namespace MIBHunter
{
    public partial class Classname : CombatRoutine
    {
        #region Delegates

        public delegate WoWPoint LocationRetriverDelegate(object context);

        #endregion

        #region Basic Functions

        public override bool WantButton
        {
            get { return true; }
        }

        public override WoWClass Class
        {
            get { return WoWClass.Hunter; }
        }

        public override string Name
        {
            get { return "MIBHunter [Version 1.0]"; }
        }

        //public override Composite RestBehavior
        //{
            //get { return RestRotation(); }
        //}

        public override Composite PreCombatBuffBehavior
        {
            get { return MainRotation(); }
        }

        public override Composite CombatBehavior
        {
            get { return MainRotation(); }
        }

        public static LocalPlayer Me
        {
            get { return StyxWoW.Me; }
        }

        public string GCDCheckSpell;

        public override void Initialize()
        {
            Logging.Write("");
            Logging.Write("Hallo Level " + Me.Level + " " + Me.Race + " " + Me.Class);
            Logging.Write("");
            Logging.Write("Danke dass du meine Routine verwendest!");
            Logging.Write("");
            Logging.Write("Am besten funktioniert diese Routine mit LazyRaider.");
            Logging.Write("Bitte achte darauf dass NUR 3 Haken gesetzt sind:");
            Logging.Write("* Run Without a Tank (no leader)");
            Logging.Write("* Disable Plug-ins");
            Logging.Write("* Frame Lock");
            Logging.Write("");

            //Disable for speed
            Lua.Events.AttachEvent("GROUP_ROSTER_UPDATE", UpdateGroupChangeEvent);
            Lua.Events.AttachEvent("ACTIVE_TALENT_GROUP_CHANGED", UpdateStatusEvent);
            Lua.Events.AttachEvent("PLAYER_TALENT_UPDATE", UpdateMyTalentEvent);
            Lua.Events.AttachEvent("GLYPH_ADDED", UpdateMyGlyphEvent);

            BotEvents.OnBotStarted += OnBotStartedEvent;

            MIBSettings.Instance.UpdateStatus = true;

            GCDCheckSpell = "Stance of the Fierce Tiger";
            //Always set AoE to true at start
            MIBSettings.Instance.AoE = true;
        }

        public override void OnButtonPress()
        {
            var gui = new MIBHunterGUI();
            gui.ShowDialog();
        }

        #endregion

        #region Function After this Region Order Alphabetically

        #endregion

        #region GetUnits

        public List<WoWUnit> FarFriendlyPlayers = new List<WoWUnit>();
        public List<WoWUnit> FarFriendlyUnits = new List<WoWUnit>();
        public List<WoWUnit> NearbyFriendlyPlayers = new List<WoWUnit>();
        public List<WoWUnit> NearbyFriendlyUnits = new List<WoWUnit>();
        public List<WoWUnit> NearbyUnFriendlyPlayers = new List<WoWUnit>();
        public List<WoWUnit> NearbyUnFriendlyUnits = new List<WoWUnit>();

        public void GetUnits()
        {
            NearbyFriendlyPlayers.Clear();
            NearbyUnFriendlyPlayers.Clear();
            NearbyFriendlyUnits.Clear();
            NearbyUnFriendlyUnits.Clear();
            FarFriendlyPlayers.Clear();
            FarFriendlyUnits.Clear();

            NearbyFriendlyUnits.Add(Me);
            NearbyFriendlyPlayers.Add(Me);
            FarFriendlyUnits.Add(Me);
            FarFriendlyPlayers.Add(Me);

            IEnumerable<WoWUnit> units =
                ObjectManager.GetObjectsOfType<WoWUnit>(true, false).Where(p => ValidUnit(p) && p.Distance < 60);

            foreach (WoWUnit unit in units)
            {
                if (unit.Entry == 62442 && !unit.Attackable) //Tsulong
                {
                    NearbyFriendlyPlayers.Add(unit);
                }
                //using (StyxWoW.Memory.AcquireFrame())
                {
                    if (IsMyPartyRaidMember(unit))
                    {
                        FarFriendlyUnits.Add(unit);

                        var player = unit as WoWPlayer;
                        if (player != null)
                        {
                            FarFriendlyPlayers.Add(unit);
                        }

                        if (unit.Distance < 40)
                        {
                            NearbyFriendlyUnits.Add(unit);

                            if (player != null)
                            {
                                NearbyFriendlyPlayers.Add(player);
                            }
                        }
                    }
                    else if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
                    {
                        if (unit.Distance > 40)
                        {
                            continue;
                        }
                        NearbyUnFriendlyUnits.Add(unit);

                        var player = unit as WoWPlayer;
                        if (player != null)
                        {
                            NearbyUnFriendlyPlayers.Add(player);
                        }
                    }
                    else if (IsEnemy(unit))
                    {
                        if (unit.Distance > 40)
                        {
                            continue;
                        }
                        NearbyUnFriendlyUnits.Add(unit);

                        var player = unit as WoWPlayer;
                        if (player != null)
                        {
                            NearbyUnFriendlyPlayers.Add(player);
                        }
                    }
                }
            }
        }

        #endregion

        #region GetUnitHeal

        public WoWUnit UnitHeal;

        private void GetUnitHeal()
        {
            UnitHeal = null;
            //Tsulong override
            if (Me.GotTarget && Me.CurrentTarget.Entry == 62442 &&
                (!Me.CurrentTarget.Attackable || Me.CurrentTarget.IsFriendly))
            {
                if (UnitHeal == null ||
                    (UnitHeal != null && UnitHeal != Me.CurrentTarget &&
                     UnitHeal.HealthPercent > MIBSettings.Instance.UrgentHeal))
                {
                    UnitHeal = Me.CurrentTarget;
                    return;
                }
            }

            if (Me.FocusedUnit != null && Me.FocusedUnit.Entry == 62442 &&
                (!Me.FocusedUnit.Attackable || Me.FocusedUnit.IsFriendly))
            {
                if (UnitHeal == null ||
                    (UnitHeal != null && UnitHeal != Me.FocusedUnit &&
                     UnitHeal.HealthPercent > MIBSettings.Instance.UrgentHeal))
                {
                    UnitHeal = Me.FocusedUnit;
                    return;
                }
            }

            if (Healable(Me.CurrentTarget) && Me.CurrentTarget != UnitHealFull &&
                Me.CurrentTarget.HealthPercent < MIBSettings.Instance.DoNotHealAbove &&
                (Me.CurrentTarget.IsPlayer || Me.CurrentTarget.IsPet))
            {
                UnitHeal = Me.CurrentTarget;
            }
            else if (Me.FocusedUnit != null &&
                     (Healable(Me.FocusedUnit) &&
                      Me.FocusedUnit != UnitHealFull &&
                      Me.FocusedUnit.HealthPercent < MIBSettings.Instance.DoNotHealAbove &&
                      (Me.FocusedUnit.IsPlayer || Me.FocusedUnit.IsPet) &&
                      !Me.CurrentMap.IsArena))
            {
                UnitHeal = Me.FocusedUnit;
            }
            else if (Me.HealthPercent < MIBSettings.Instance.PriorityHeal &&
                     Me != UnitHealFull && !Me.CurrentMap.IsArena)
            {
                UnitHeal = Me;
            }
            else
            {
                //using (StyxWoW.Memory.AcquireFrame())
                {
                    UnitHeal = (from unit in NearbyFriendlyUnits
                                orderby unit.HealthPercent ascending
                                where unit != UnitHealFull
                                where unit.IsPlayer || Me.CurrentMap.IsArena && unit.IsPet
                                where Healable(unit)
                                select unit).FirstOrDefault();
                }
            }
        }

        #endregion

        #region GetUnitAttack

        public WoWUnit UnitAttack;
        public WoWUnit UnitAttackPet;

        private void GetUnitAttack()
        {
            UnitAttack = null;
            UnitAttackPet = null;

            {
                if (!SpellManager.HasSpell("Holy Insight"))
                {
                    UnitAttack = (from unit in NearbyUnFriendlyUnits
                                  //Only search Target if in instance
                                  //where Me.IsInInstance
                                  orderby unit.Distance ascending
                                  //attack any unit if not in dungeon/raid
                                  where unit.Combat
                                  //where unit.GotTarget
                                  //only attack unit not tagged
                                  where
                                      unit.IsTargetingMeOrPet ||
                                      unit.IsTargetingMyPartyMember ||
                                      unit.IsTargetingMyRaidMember ||
                                      unit.IsPlayer && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();
                }
                else
                {
                    UnitAttack = (from unit in NearbyUnFriendlyUnits
                                  //Only search Target if in instance
                                  //where Me.IsInInstance
                                  orderby unit.HealthPercent ascending
                                  //attack any unit if not in dungeon/raid
                                  where unit.Combat
                                  //where unit.GotTarget
                                  //only attack unit not tagged
                                  where
                                      unit.IsTargetingMeOrPet ||
                                      unit.IsTargetingMyPartyMember ||
                                      unit.IsTargetingMyRaidMember ||
                                      unit.IsPlayer && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();
                }
                //if it pet, try to find a player
                if (UnitAttack != null && !UnitAttack.IsPlayer && !Me.CurrentMap.IsRaid && !Me.CurrentMap.IsDungeon)
                {
                    UnitAttackPet = UnitAttack;
                    UnitAttack = (from unit in NearbyUnFriendlyPlayers
                                  orderby unit.Distance ascending
                                  where unit.Combat && unit.IsTargetingMeOrPet || Me.CurrentMap.IsBattleground
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();

                    //can't find a player, kill the pet
                    if (UnitAttack == null && UnitAttackPet != null)
                    {
                        UnitAttack = UnitAttackPet;
                    }
                }
            }
        }

        #endregion

        #region GroupMembers

        internal static IEnumerable<WoWPartyMember> GroupMembers
        {
            get { return !Me.GroupInfo.IsInRaid ? Me.GroupInfo.PartyMembers : Me.GroupInfo.RaidMembers; }
        }

        #endregion

        #region Pulse

        public DateTime LastSwitch;
        public DateTime BurstLast;

        public override void Pulse()
        {
            if (MIBSettings.Instance.UpdateStatus)
            {
                UpdateStatus();
                InputBlockCheck();
            }
            else
            {
                ObjectManager.Update();
                GetUnits();
                GetUnitHeal();
                StopCastingCheck();
                GetUnitAttack();
                InputBlockCheck();

                //Pause
                if (MIBSettings.Instance.PauseKeyUse && MIBSettings.Instance.PauseKey != 0)
                {
                    //Pause Mode
                    if (GetAsyncKeyState(Keys.LControlKey) < 0 &&
                        GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.PauseKey)) < 0 &&
                        LastSwitch.AddSeconds(1) < DateTime.Now) 
                    {
                        if (MIBSettings.Instance.Pause)
                        {
                            MIBSettings.Instance.Pause = false;
                            LastSwitch = DateTime.Now;
                            Logging.Write("Pause Mode is OFF, Ctrl + " +
                                          IndexToKeys(MIBSettings.Instance.PauseKey) +
                                          " to Override bot action.");
                            Lua.DoString("RunMacroText(\"/script msg='Pause Mode OFF' print(msg)\")");
                        }
                        else
                        {
                            MIBSettings.Instance.Pause = true;
                            LastSwitch = DateTime.Now;
                            Logging.Write("Pause Mode is ON, Ctrl + " +
                                          IndexToKeys(MIBSettings.Instance.PauseKey) +
                                          " to resume bot action.");
                            Lua.DoString("RunMacroText(\"/script msg='Pause Mode ON' print(msg)\")");
                        }
                    }
                }

                //AoE Mode
                if (MIBSettings.Instance.AoEKeyUse && MIBSettings.Instance.AoEKey != 0)
                {
                    //Pause Mode
                    if (GetAsyncKeyState(Keys.LControlKey) < 0 &&
                        GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.AoEKey)) < 0 &&
                        LastSwitch.AddSeconds(1) < DateTime.Now) 
                    {
                        if (MIBSettings.Instance.AoE)
                        {
                            MIBSettings.Instance.AoE = false;
                            LastSwitch = DateTime.Now;
                            Logging.Write("AoE Mode is OFF, Ctrl + " +
                                          IndexToKeys(MIBSettings.Instance.AoEKey) +
                                          " to toggle AoE Mode ON.");
                            Lua.DoString("RunMacroText(\"/script msg='AoE Mode OFF' print(msg)\")");
                        }
                        else
                        {
                            MIBSettings.Instance.AoE = true;
                            LastSwitch = DateTime.Now;
                            Logging.Write("AoE Mode is ON, Ctrl + " +
                                          IndexToKeys(MIBSettings.Instance.AoEKey) +
                                          " to toggle AoE Mode OFF.");
                            Lua.DoString("RunMacroText(\"/script msg='AoE Mode ON' print(msg)\")");
                        }
                    }
                }

                //Auto Disactivate Burst after a Timer or Me get CC
                if (MIBSettings.Instance.Burst && (BurstLast < DateTime.Now || DebuffCC(Me)))
                {
                    MIBSettings.Instance.Burst = false;
                    BurstLast = DateTime.Now;
                    Logging.Write("Burst Mode is OFF");
                    Lua.DoString("RunMacroText(\"/script msg='Burst Mode OFF' print(msg)\")");
                }

                //Burst on Cooldown
                if (MIBSettings.Instance.BurstKey == 1 && MIBSettings.Instance.Burst == false &&
                    !DebuffCC(Me))
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated On Cooldown");
                    MIBSettings.Instance.Burst = true;
                }

                //Burst on Cooldown (Boss Only)
                if (MIBSettings.Instance.BurstKey == 2 && MIBSettings.Instance.Burst == false &&
                    Attackable(Me.CurrentTarget, 15) && Me.CurrentTarget.IsBoss &&
                    !DebuffCC(Me))
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated On Cooldown (Boss Only)");
                    MIBSettings.Instance.Burst = true;
                }

                //Burst on Bloodlust
                if (MIBSettings.Instance.BurstKey == 3 && MIBSettings.Instance.Burst == false &&
                    (Me.HasAura("Bloodlust") || Me.HasAura("Heroism") || Me.HasAura("Time Warp") ||
                     Me.HasAura("Ancient Hysteria")) && !DebuffCC(Me))
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated On Bloodlust/Heroism/Time Warp/Ancient Hysteria");
                    MIBSettings.Instance.Burst = true;
                }

                //Burst On My Health Below
                if (MIBSettings.Instance.BurstKey == 4 && MIBSettings.Instance.Burst == false &&
                    Me.HealthPercent < MIBSettings.Instance.BurstHP && !DebuffCC(Me))
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on My Health Low");
                    MIBSettings.Instance.Burst = true;
                }

                //Burst On My Friend Health Below
                if (MIBSettings.Instance.BurstKey == 5 && MIBSettings.Instance.Burst == false &&
                    UnitHeal != null && UnitHeal.IsValid &&
                    UnitHeal.HealthPercent < MIBSettings.Instance.BurstHP && !DebuffCC(Me))
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on My Friend Health Low");
                    MIBSettings.Instance.Burst = true;
                }

                //Burst On Enemy Health Below
                if (MIBSettings.Instance.BurstKey == 6 && MIBSettings.Instance.Burst == false &&
                    Me.CurrentTarget != null && Me.CurrentTarget.IsValid &&
                    ValidUnit(Me.CurrentTarget) &&
                    IsEnemy(Me.CurrentTarget) &&
                    !Me.CurrentTarget.IsPet &&
                    Me.HealthPercent > MIBSettings.Instance.UrgentHeal &&
                    Me.CurrentTarget.HealthPercent < MIBSettings.Instance.BurstHP && !DebuffCC(Me))
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on Enemy Health Low");
                    MIBSettings.Instance.Burst = true;
                }

                //Burst by key press
                if (MIBSettings.Instance.BurstKey > 6)
                {
                    //Burst Mode
                    if (GetAsyncKeyState(Keys.LControlKey) < 0 &&
                        GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.BurstKey - 6)) < 0 &&
                        LastSwitch.AddSeconds(1) < DateTime.Now) // && GetActiveWindowTitle() == "World of Warcraft")
                    {
                        if (MIBSettings.Instance.Burst)
                        {
                            MIBSettings.Instance.Burst = false;
                            LastSwitch = DateTime.Now;
                            Logging.Write("Burst Mode is OFF, Ctrl + " +
                                          IndexToKeys(MIBSettings.Instance.BurstKey - 6) +
                                          " to Turn Burst Mode ON.");
                            Lua.DoString("RunMacroText(\"/script msg='Burst Mode OFF' print(msg)\")");
                        }
                            //else if (DebuffCC(Me))
                            //{
                            //    MIBSettings.Instance.Burst = false;
                            //    LastSwitch = DateTime.Now;
                            //    Logging.Write("Burst Mode is OFF, You Got Crowd Control, Ctrl + " +
                            //                  IndexToKeys(MIBSettings.Instance.BurstKey - 6) +
                            //                  " to Turn Burst Mode ON.");
                            //    Lua.DoString("RunMacroText(\"/script msg='Burst Mode OFF' print(msg)\")");
                            //}
                        else if (!DebuffCC(Me))
                        {
                            MIBSettings.Instance.Burst = true;
                            LastSwitch = DateTime.Now;
                            BurstLast = DateTime.Now.AddSeconds(15);
                            Logging.Write("Burst Mode is ON, Ctrl + " +
                                          IndexToKeys(MIBSettings.Instance.BurstKey - 6) +
                                          " to Turn Burst Mode OFF.");
                            Lua.DoString("RunMacroText(\"/script msg='Burst Mode ON' print(msg)\")");
                        }
                    }
                }
            }
        }

        #endregion

        #region MainRotation

        public bool HelloFriend = false;
        public bool IsConstantFace;
        public bool IsOverrideModeOn;
        public WoWUnit MyLastTarget;
        public DateTime Now = DateTime.Now;
        public Stopwatch PendingSpellStopWatch = new Stopwatch();
        public DateTime TickMilisecond;
        public DateTime TickMilisecondTotal;
        public WoWUnit UnitHealFull;
        public DateTime DoNotMove;

        public Composite MainRotation()
        {
            return new PrioritySelector(
                new Decorator(
                    ret => MIBSettings.Instance.Pause,
                    new Action(delegate { return RunStatus.Success; })),
                new Decorator(
                    ret =>
                    MIBSettings.Instance.UpdateStatus,
                    new Action(delegate
                        {
                            return RunStatus.Success;
                        })),
                new Decorator(
                    ret => (Me.HasAura("Resurrection Sickness") ||
                            !StyxWoW.IsInWorld ||
                            !Me.IsValid),
                    new Action(delegate
                        {
                            MIBSettings.Instance.UpdateStatus = true;
                            Logging.Write(LogLevel.Diagnostic,
                                          "Wiederbelebungsnachwirkungen oder nicht in WoW, Überspringe Hauptrotation.");
                            return RunStatus.Success;
                        })),
                //Trying to stop bot movement while casting
                new Decorator(
                    ret =>
                    TreeRoot.Current.Name != "LazyRaider" &&
                    TreeRoot.Current.Name != "Raid Bot" &&
                    TreeRoot.Current.Name != "Combat Bot" &&
                    DoNotMove > DateTime.Now,
                    new Action(delegate { return RunStatus.Success; })
                    ),
                new Action(delegate
                    {
                        if (Me.IsInInstance && EventHandlers.CombatLogAttached)
                        {
                            EventHandlers.DetachCombatLogEvent();
                        }

                        if (!Me.IsInInstance && !EventHandlers.CombatLogAttached)
                        {
                            EventHandlers.AttachCombatLogEvent();
                        }

                        if (!IsOverrideModeOn &&
                            //Do not stop movement in LazyRaider if SMoveToTarget enabled
                            //TreeRoot.Current.Name != "LazyRaider" &&
                            (GetAsyncKeyState(Keys.LButton) != 0 &&
                             GetAsyncKeyState(Keys.RButton) != 0) ||
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.StrafleLeft)) != 0 &&
                            IndexToKeys(MIBSettings.Instance.StrafleLeft) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.Forward)) != 0 &&
                            IndexToKeys(MIBSettings.Instance.Forward) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.StrafleRight)) != 0 &&
                            IndexToKeys(MIBSettings.Instance.StrafleRight) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.TurnLeft)) != 0 &&
                            IndexToKeys(MIBSettings.Instance.TurnLeft) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.Backward)) != 0 &&
                            IndexToKeys(MIBSettings.Instance.Backward) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.TurnRight)) != 0 &&
                            IndexToKeys(MIBSettings.Instance.TurnRight) != Keys.None)
                        {
                            IsOverrideModeOn = true;
                        }

                        if (IsOverrideModeOn &&
                            //Do not stop movement in LazyRaider if SMoveToTarget enabled
                            //TreeRoot.Current.Name != "LazyRaider" &&
                            GetAsyncKeyState(Keys.LButton) == 0 &&
                            GetAsyncKeyState(Keys.RButton) == 0 &&
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.StrafleLeft)) == 0 &&
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.Forward)) == 0 &&
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.StrafleRight)) == 0 &&
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.TurnLeft)) == 0 &&
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.Backward)) == 0 &&
                            GetAsyncKeyState(IndexToKeys(MIBSettings.Instance.TurnRight)) == 0)
                        {
                            IsOverrideModeOn = false;
                        }

                        if (GetAsyncKeyState(Keys.F9) != 0)
                        {
                            Logging.Write("Hauptrotation braucht " +
                                          Math.Round((DateTime.Now -
                                                      TickMilisecondTotal).TotalMilliseconds) +
                                          " ms");
                            TickMilisecondTotal = DateTime.Now;
                        }

                        //GetAllMyAuras
                        if (GetAsyncKeyState(Keys.F10) != 0)
                        {
                            DumpAuras();
                        }

                        //GroupMember
                        if (GetAsyncKeyState(Keys.F11) != 0)
                        {
                            Logging.Write("Liste der Gruppennummern");
                            foreach (var woWPartyMember in GroupMembers)
                            {
                                if (woWPartyMember.ToPlayer() != null)
                                {
                                    Logging.Write(woWPartyMember.ToPlayer().Name + " in Gruppe " +
                                                  woWPartyMember.GroupNumber);
                                }
                            }
                        }

                        //Get target back after a fear
                        if (Me.CurrentTarget != null && MyLastTarget != Me.CurrentTarget)
                        {
                            MyLastTarget = Me.CurrentTarget;
                        }

                        //Clear Target if dead and still in combat
                        if (Me.CurrentTarget != null && !Me.CurrentTarget.IsAlive && Me.Combat)
                        {
                            Lua.DoString("RunMacroText(\"/cleartarget\")");
                        }

                        //Clear Target if walk away from friendly
                        if (Me.CurrentTarget != null && !Me.CurrentTarget.IsPlayer &&
                            Me.CurrentTarget.IsFriendly &&
                            Me.CurrentTarget.IsSafelyBehind(Me))
                        {
                            Lua.DoString("RunMacroText(\"/cleartarget\")");
                        }

                        //Death Knight Dark Simulacrum
                        //if (Me.HasAura("Dark Simulacrum"))
                        //{
                        //    CastSpell("Seal of Insight", Me);
                        //    return RunStatus.Success;
                        //}

                        return RunStatus.Failure;
                    }
                    ),
                Hold(),
                UseTrinket(),
                UseProfession(),
                UseHealthstone(),
                UseBattleStandard(),
                SetAutoAttack(),
                UseRacial(),
                CheckStance(),
                new Decorator(
                    ret =>
                    Me.Specialization == WoWSpec.HunterBeastMastery,
                    BeastMasteryRotation()
                    ),
                new Decorator(
                    ret =>
                    Me.Specialization == WoWSpec.HunterMarksmanship,
                    MarksmanshipRotation()
                    ),
                new Decorator(
                    ret =>
                    Me.Specialization == WoWSpec.HunterSurvival,
                    SurvivalRotation()
                    )
                );
        }

        #endregion
    }
}